/**
 * 总结性： (不完全)
 * this的指向基本原则: 谁调用this的宿主，this就指向谁
 */

const test2 = () => {
  console.log(this.b) // undefined
  console.log(this.obj.b) // 2
}

var obj = {
  a: 1,
  b: 2,
  test: function() {
    // this -> obj
    console.log(this.a)
  },
  test2: test2,
  c: {
    d: 4,
    test3: function() {
      // this -> obj.c
      console.log(this); // {d: 4 , test3: ƒ}
      console.log(this.d); // 4
    }
  }
}

// function test2() {
//   console.log(this.b) // this -> obj
// }

obj.test(); // 1
obj.test2(); // 2
obj.c.test3();

// 原理： 对象方法内部的this -> 最近的引用

var obj2 = {
  a: 1,
  b: 2,
  test3: function() {
    // t() 不是obj2的成员，不属于obj2，也不属于test3，是孤立的
    function t() {
      // this -> window
      // 最近的引用就是window
      console.log(this);
    }
    t();
  }
}

// function t() {
//   // this -> window
// }

obj2.test3();

obj2.__proto__ = {
  e: 20
}
console.log(obj2.e) // 20

var obj3 = Object.create({
  test4: function() {
    // this -> obj
    console.log(this);
    console.log(this.a + this.b);
  }
})
obj3.a = 1;
obj3.b = 2;
// console.log(obj3.test4);
obj3.test4(); // 继承来的

// 从调用的角度来说与上面的一样
// var obj3 = {
//   a: 1,
//   b: 2,
//   test4: function () {
//     console.log(this.a + this.b)
//   }
// }

// obj3.test4()

/**
 * 1. test4 由 obj3 调用
 * 2. obj3 就是test4 最近的引用
 * 3. test4的this -> obj3
 * 4. obj3 = { tes4 x } obj3上没有test4方法
 * 5. obj3 —> __proto__ -> prototype对象
 * 6. 直到找到Object.prototype 为止
 * 7. 只要链上 有 test4 直接调用
 * 8. 如果找不到 就报错 -> undefined
 * 9. undefined 无法执行 -> not a function (TypeError 类型错误)
 */
